package com.ferry.config.client.loader;

import com.fasterxml.jackson.core.type.TypeReference;
import com.ferry.config.client.enumValue.Env;
import com.ferry.config.client.monitor.ConfigMonitor;
import com.ferry.config.client.util.JsonUtil;
import com.ferry.config.client.vo.ConfigRepository;
import com.ferry.config.client.vo.GetData;
import com.google.common.collect.Maps;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.SocketConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;


/**
 * Created by daiyong
 * 全量拉取配置
 */
public class HttpGetClassLoader extends AbstractConfigLoader{

	private static final Logger LOGGER = LoggerFactory.getLogger(HttpGetClassLoader.class);

	private static final Integer PULL_PERIOD = 100000;  //10s 拉取一次

	private ScheduledExecutorService getExecutorService = Executors.newScheduledThreadPool(1, new ThreadFactory() {
				public Thread newThread(Runnable r) {
					Thread t = Executors.defaultThreadFactory().newThread(r);
					t.setName("fconfig-http-get");
					return t;
				}
			}
	);

	public HttpGetClassLoader(String namespace, String env, ConfigMonitor configMonitor) {
		super(configMonitor, namespace, env);
	}

	@Override
	public void start() {

		initHttp();

		//初始化本地缓存
		configMonitor.fillConfigRepository(doPollWithRetry(3));

		//每隔10s 全量获取一次数据
		getExecutorService.scheduleWithFixedDelay(new Runnable() {
			@Override
			public void run() {
				try {
					configMonitor.fillConfigRepository(doPollWithRetry(3));
				} catch (Exception e) {
					LOGGER.error("HttpGetClassLoader.loadData Exception", e);
				}
			}
		}, PULL_PERIOD, PULL_PERIOD, TimeUnit.MILLISECONDS);
	}

	private List<GetData> doPollWithRetry(int maxTries){

		int tryCount = 1;
		do {
			CloseableHttpResponse response = null;
			Env env = Env.lookUp(this.env);
			try {
				HttpPost post = new HttpPost(env.getGetUrl());
				List<NameValuePair> parameters = new ArrayList<NameValuePair>(0);
				parameters.add(new BasicNameValuePair("nameSpace", this.namespace));
				// 构造一个form表单式的实体
				UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters);
				// 将请求实体设置到httpPost对象中
				post.setEntity(formEntity);
				response = httpClient.execute(post);
				if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
					String result = EntityUtils.toString(response.getEntity(), "UTF-8");
					if (StringUtils.isNotBlank(result)) {
						List<GetData> getDatas = JsonUtil.fromJson(result, new TypeReference<List<GetData>>() {
						});
						return getDatas;
					}
				}
			} catch (Exception e) {
				LOGGER.error("doPollWithRetry Exception", e);
			}  finally {
				try {
					if (response != null) {
						response.close();
					}
				} catch (IOException e) {
					//ignore
				}
			}
		} while (tryCount++ < maxTries);

		return null;
	}
}

